home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 176-200 / 190 / nethack / twee.zoo / spell.c < prev    next >
C/C++ Source or Header  |  1988-07-24  |  10KB  |  442 lines

  1. /*    SCCS Id: @(#)spell.c    2.3     87/12/12
  2.  */
  3.  
  4. #include "hack.h"
  5. #ifdef SPELLS
  6. extern char *nomovemsg;
  7.  
  8. doxcribe() {
  9.     register struct obj *book;
  10.     struct     obj    *getobj();
  11.     register boolean confused = (Confusion != 0);
  12.     register boolean oops;
  13.     register schar     delay;
  14.     register int   booktype;
  15.     register int     i;
  16.  
  17.     book = getobj("+", "transcribe");
  18.     if(!book) return(0);
  19.  
  20.     if(Blind) {
  21.         pline("Being blind, you cannot read the mystic runes.");
  22.         useup(book);                /* well, if you are stupid... */
  23.         return(0);
  24.     }
  25.  
  26.     if(confused) {
  27.         pline("Being confused, you cannot grasp the meaning of this tome.");
  28.         useup(book);                /* and more stupidity... */
  29.         return(0);
  30.     }
  31.     booktype = book->otyp;
  32.     oops = !rn2(u.ulevel - objects[booktype].spl_lev + 7);
  33.     switch(booktype)  {
  34.  
  35. /* level 1 spells */
  36.     case SPE_HEALING:
  37.     case SPE_DETECT_MONSTERS:
  38.     case SPE_FORCE_BOLT:
  39.     case SPE_LIGHT:
  40.     case SPE_SLEEP:
  41. /* level 2 spells */
  42.     case SPE_MAGIC_MISSILE:
  43.     case SPE_CONFUSE_MONSTER:
  44.     case SPE_SLOW_MONSTER:
  45.     case SPE_CURE_BLINDNESS:
  46.     case SPE_CREATE_MONSTER:
  47.     case SPE_DETECT_FOOD:
  48.         delay = -objects[booktype].oc_delay;
  49.         break;
  50. /* level 3 spells */
  51.     case SPE_HASTE_SELF:
  52.     case SPE_CAUSE_FEAR:
  53.     case SPE_CURE_SICKNESS:
  54.     case SPE_DETECT_UNSEEN:
  55.     case SPE_EXTRA_HEALING:
  56.     case SPE_CHARM_MONSTER:
  57. /* level 4 spells */
  58.     case SPE_LEVITATION:
  59.     case SPE_RESTORE_STRENGTH:
  60.     case SPE_INVISIBILITY:
  61.     case SPE_FIREBALL:
  62.     case SPE_DETECT_TREASURE:
  63.         delay = -(objects[booktype].spl_lev - 1) * objects[booktype].oc_delay;
  64.         break;
  65. /* level 5 spells */
  66.     case SPE_REMOVE_CURSE:
  67.     case SPE_MAGIC_MAPPING:
  68.     case SPE_CONE_OF_COLD:
  69.     case SPE_IDENTIFY:
  70.     case SPE_DIG:
  71. /* level 6 spells */
  72.     case SPE_TURN_UNDEAD:
  73.     case SPE_POLYMORPH:
  74.     case SPE_CREATE_FAMILIAR:
  75.     case SPE_TELEPORT_AWAY:
  76.         delay = -objects[booktype].spl_lev * objects[booktype].oc_delay;
  77.         break;
  78. /* level 7 spells */
  79.     case SPE_CANCELLATION:
  80.     case SPE_FINGER_OF_DEATH:
  81.     case SPE_GENOCIDE:
  82.         delay = -8 * objects[booktype].oc_delay;
  83.         break;
  84. /* impossible */
  85.     default:
  86.         impossible("Unknown spell-book, %d;", booktype);
  87.         return(0);
  88.     }
  89.  
  90.     pline("You begin to transcribe the spell.");
  91.     if(oops || book->cursed)  {
  92.         cursed_book(objects[booktype].spl_lev);
  93.         nomul(delay);                   /* study time */
  94.     } else    {
  95.         nomul(delay);                   /* study time */
  96.         for(i = 0; i < MAXSPELL; i++)  {
  97.             if(spl_book[i].sp_id == booktype)  {
  98. #ifdef HARD
  99.             nomovemsg = "You make that spell more legible.";
  100.             spl_book[i].sp_uses += rn1(3,8-spl_book[i].sp_lev);
  101. #else
  102.             nomovemsg = "Oh, you already know that one!";
  103. #endif
  104.             useup(book);
  105.             return(1);
  106.             } else if (spl_book[i].sp_id == NO_SPELL)  {
  107.             spl_book[i].sp_id = booktype;
  108.             spl_book[i].sp_lev = objects[booktype].spl_lev;
  109.             spl_book[i].sp_flags = objects[booktype].bits;
  110. #ifdef HARD
  111.             /* spells have 2 .. 10-level uses. */
  112.             /* ie 2 or 3 uses w/ most potent */
  113.             spl_book[i].sp_uses = rn1(3,8-spl_book[i].sp_lev);
  114. #endif
  115.             nomovemsg = "You add the spell to your books.";
  116.             objects[booktype].oc_name_known = 1;
  117.             useup(book);
  118.             return(1);
  119.             }
  120.         }
  121.         impossible("Too many spells in spellbook!");
  122.     }
  123.     useup(book);
  124.     return(1);
  125. }
  126.  
  127. cursed_book(level)
  128.     register int    level;
  129. {
  130.     switch(rn2(level)) {
  131.     case 0:
  132.         pline("You feel a wrenching sensation.");
  133.         tele();         /* teleport him */
  134.         break;
  135.     case 1:
  136.         pline("You feel threatened.");
  137.         aggravate();
  138.         break;
  139.     case 2:
  140.         if(!Blind)      pline("A cloud of darkness falls upon you.");
  141.         Blinded += rn1(100,250);
  142.         seeoff(0);
  143.         break;
  144.     case 3:
  145.         if (u.ugold <= 0)  {
  146.             pline("You feel a strange sensation.");
  147.         } else {
  148.             pline("You notice you have no gold!");
  149.             u.ugold = 0;
  150.             flags.botl = 1;
  151.         }
  152.         break;
  153.     case 4:
  154.         pline("These runes were just too much to comprehend.");
  155.         HConfusion += rn1(7,16);
  156.         break;
  157.     case 5:
  158.         pline("The book was coated with contact poison!");
  159.         if(Poison_resistance) {
  160.             losestr(rn1(1,2));
  161.             losehp(rnd(6), "contact poison");
  162.         } else {
  163.             losestr(rn1(4,3));
  164.             losehp(rnd(10), "contact poison");
  165.         }
  166.         break;
  167.     case 6:
  168.         pline("As you read the book, it explodes in your face!");
  169.         losehp (2*rnd(10)+5, "exploding rune");
  170.         break;
  171.     default:
  172.         rndcurse();
  173.         break;
  174.     }
  175.     return(0);
  176. }
  177.  
  178. docast()
  179. {
  180.     register int     spell, energy, damage;
  181.     register boolean confused = (Confusion != 0);
  182.     register struct  obj    *pseudo;
  183.     struct     obj     *mksobj();
  184.  
  185.     spell = getspell();
  186.     if (!spell) return(0);
  187.     else  {
  188. #ifdef HARD
  189.         /* note that turning to the page decrements the # of uses,  */
  190.         /* even if the mage does not have enough food/energy to use */
  191.         /* the spell */
  192.         switch (spelluses(spell)) {
  193.         case 0:
  194.             pline ("That page is too faint to read at the moment.");
  195.             return(0);
  196.         case 1:
  197.             pline ("You can barely make out the runes on this page.");
  198.             break;
  199.         case 2:
  200.             pline ("This spell is starting to look well used.");
  201.             break;
  202.         default:
  203.             break;
  204.         }
  205.         decrnuses(spell);
  206. #endif
  207.         energy = spellev(spell);
  208. #ifdef BVH
  209.         if (has_amulet()) {
  210.  
  211.             pline("You feel the amulet draining your energy away.");
  212.             energy *= rnd(6);
  213.         }
  214. #endif
  215.         if(energy > u.uen)  {
  216.             pline("You are too weak to cast that spell.");
  217.             return(0);
  218.         } else    if ((u.uhunger <= 100) || (u.ustr < 6))  {
  219.             pline("You miss the strength for that spell.");
  220.             return(0);
  221.         } else    {
  222.             morehungry(energy * 10);
  223.             u.uen -= energy;
  224.         }
  225.         flags.botl = 1;
  226.     }
  227. #ifdef HARD
  228.     if (confused ||
  229.         (rn2(10) + (int)(u.ulevel + u.uluck) - 3*spellev(spell)) < 0) {
  230.  
  231.         if (Hallucination)
  232.             pline("Far out... a light show!");
  233.         else    pline("The air around you crackles as you goof up.");
  234.         return(0);
  235.     }
  236. #endif
  237.  
  238. /*    pseudo is a temporary "false" object containing the spell stats. */
  239.     pseudo = mksobj(spellid(spell));
  240.     pseudo->quan = 20;            /* do not let useup get it */
  241.     switch(pseudo->otyp)  {
  242.  
  243. /* These spells are all duplicates of wand effects */
  244.     case SPE_FORCE_BOLT:
  245.     case SPE_SLEEP:
  246.     case SPE_MAGIC_MISSILE:
  247.     case SPE_SLOW_MONSTER:
  248.     case SPE_FIREBALL:
  249.     case SPE_CONE_OF_COLD:
  250.     case SPE_DIG:
  251.     case SPE_TURN_UNDEAD:
  252.     case SPE_POLYMORPH:
  253.     case SPE_TELEPORT_AWAY:
  254.     case SPE_CANCELLATION:
  255.     case SPE_FINGER_OF_DEATH:
  256.     case SPE_LIGHT:
  257.     case SPE_DETECT_UNSEEN:
  258.         if (!(objects[pseudo->otyp].bits & NODIR)) {
  259.             getdir(1);
  260.             if(!u.dx && !u.dy && !u.dz && (u.ulevel > 8)) {
  261.                 if((damage = zapyourself(pseudo)))
  262.                 losehp(damage, "self-inflicted injury");
  263.             } else    weffects(pseudo);
  264.         } else weffects(pseudo);
  265.         break;
  266. /* These are all duplicates of scroll effects */
  267.     case SPE_CONFUSE_MONSTER:
  268.     case SPE_DETECT_FOOD:
  269.     case SPE_CAUSE_FEAR:
  270.     case SPE_CHARM_MONSTER:
  271.     case SPE_REMOVE_CURSE:
  272.     case SPE_MAGIC_MAPPING:
  273.     case SPE_CREATE_MONSTER:
  274.     case SPE_IDENTIFY:
  275.     case SPE_GENOCIDE:
  276.         seffects(pseudo);
  277.         break;
  278.     case SPE_HASTE_SELF:
  279.     case SPE_DETECT_TREASURE:
  280.     case SPE_DETECT_MONSTERS:
  281.     case SPE_LEVITATION:
  282.     case SPE_RESTORE_STRENGTH:
  283.     case SPE_INVISIBILITY:
  284.         peffects(pseudo);
  285.         break;
  286.     case SPE_HEALING:
  287.         pline("You feel a bit better.");
  288.         healup(rnd(8), 0, 0, 0);
  289.         break;
  290.     case SPE_CURE_BLINDNESS:
  291.         healup(0, 0, 0, 1);
  292.         break;
  293.     case SPE_CURE_SICKNESS:
  294.         pline("You are no longer ill.");
  295.         healup(0, 0, 1, 0);
  296.         break;
  297.     case SPE_EXTRA_HEALING:
  298.         pline("You feel a fair bit better.");
  299.         healup(d(2,8), 1, 0, 0);
  300.         break;
  301.     case SPE_CREATE_FAMILIAR:
  302.         {    register struct monst *mtmp;
  303.             struct     monst    *makedog();
  304.  
  305.             mtmp = makedog();
  306.             if(mtmp) {
  307.                 /* make it into something else */
  308.                 (void) newcham(mtmp,
  309. #ifndef RPH
  310.                 &mons[dlevel+14+rn2(CMNUM-14-dlevel)]);
  311. #else
  312.                 (struct pemonst *)0);
  313. #endif
  314.                 if(confused)
  315.                 mtmp->mtame = mtmp->mpeaceful = 0;
  316.             }
  317.         }
  318.         break;
  319.     default:
  320.         impossible("Unknown spell %d attempted.", spell);
  321.         obfree(pseudo, (struct obj *)0);
  322.         return(0);
  323.     }
  324.     obfree(pseudo, (struct obj *)0);        /* now, get rid of it */
  325.     return(1);
  326. }
  327.  
  328. getspell()  {
  329.  
  330.     register int    max, ilet, i;
  331.     char     lets[BUFSZ], buf[BUFSZ];
  332.  
  333.     if (spl_book[0].sp_id == NO_SPELL)  {
  334.  
  335.         pline("You don't know any spells right now.");
  336.         return(0);
  337.     } else    {
  338.  
  339.         for(max = 1; (max < MAXSPELL) && (spl_book[max].sp_id != NO_SPELL); max++);
  340.         if (max >= MAXSPELL)  {
  341.  
  342.         impossible("Too many spells memorized.");
  343.         return(0);
  344.         }
  345.  
  346.         for(i = 0; (i < max) && (i < 26); buf[++i] = 0)  buf[i] = 'a' + i;
  347.         for(i = 26; (i < max) && (i < 52); buf[++i] = 0) buf[i] = 'A' + i - 26;
  348.  
  349.         if (max == 1)  strcpy(lets, "a");
  350.         else if (max < 27)  sprintf(lets, "a-%c", 'a' + max - 1);
  351.         else if (max == 27)  sprintf(lets, "a-z A");
  352.         else sprintf(lets, "a-z A-%c", 'A' + max - 27);
  353.         for(;;)  {
  354.  
  355.         pline("Cast which spell [%s ?]: ", lets);
  356.         if ((ilet = readchar()) == '?')  {
  357.             dovspell();
  358.             continue;
  359.         } else if ((ilet == '\033')||(ilet == '\n')||(ilet == ' '))
  360.             return(0);
  361.         else for(i = 0; buf[i] != 0; i++)  if(ilet == buf[i])  return(++i);
  362.         pline("You don't know that spell.");
  363.         }
  364.     }
  365. }
  366.  
  367. losespells() {
  368.     register boolean confused = (Confusion != 0);
  369.     register int     n, nzap, i;
  370.  
  371.     for(n = 0;(spl_book[n].sp_id != NO_SPELL) && (n < MAXSPELL); n++);
  372.     if (!n) return;
  373.     if (n < MAXSPELL) {
  374.         nzap = rnd(n);
  375.         if (nzap < n) nzap += confused;
  376.         for (i = 0; i < nzap; i++) spl_book[n-i-1].sp_id = NO_SPELL;
  377.     } else impossible("Too many spells in spellbook!");
  378.     return;
  379. }
  380.  
  381. dovspell() {
  382.  
  383.     register int max, i, side;
  384.     extern     char morc;
  385.     char     buf[BUFSZ],
  386.          any[BUFSZ],
  387.          *spellname();
  388.  
  389.     if (spl_book[0].sp_id == NO_SPELL)  {
  390.  
  391.         pline("You don't know any spells right now.");
  392.         return(0);
  393.     }
  394.  
  395.     for(max = 1; (max < MAXSPELL) && (spl_book[max].sp_id != NO_SPELL); max++);
  396.     if (max >= MAXSPELL)  {
  397.  
  398.         impossible("Too many spells memorized.");
  399.         return(0);
  400.     }
  401.     morc = 0;        /* just to be sure */
  402.     cornline(0, "Currently known spells:");
  403.  
  404.     for(i = 1; i <= max; i++) {
  405.  
  406.         (void) sprintf(buf, "%c - %s (%d)",
  407.             spellet(i),spellname(i),spellev(i));
  408.         cornline(1, buf);
  409.         any[i-1] = spellet(i);
  410.     }
  411.     any[i-1] = 0;
  412.     cornline(2, any);
  413.  
  414.     return(0);
  415. }
  416.  
  417. spellet(spl)  {
  418.  
  419.     if (spl < 27)   return('a' + spl - 1);
  420.     else        return('A' + spl - 27);
  421. }
  422.  
  423. spellev(spl)  {
  424.  
  425.     return(spl_book[spl-1].sp_lev);
  426. }
  427.  
  428. char *
  429. spellname(spl)  {
  430.  
  431.     return(objects[spl_book[spl-1].sp_id].oc_name);
  432. }
  433.  
  434. spellid(spl)  {         return(spl_book[spl-1].sp_id);          }
  435.  
  436. #ifdef HARD
  437. spelluses(spell) {      return(spl_book[spell-1].sp_uses);      }
  438. decrnuses(spell) {      spl_book[spell-1].sp_uses--;            }
  439. #endif
  440.  
  441. #endif /* SPELLS /**/
  442.